package com.sxfq.loansupermarket.backsystem.modular.weixin.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sxfq.loansupermarket.backsystem.GunsApplication;
import com.sxfq.loansupermarket.backsystem.common.controller.BaseController;

import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.sxfq.loansupermarket.backsystem.core.shiro.ShiroKit;
import com.sxfq.loansupermarket.backsystem.modular.IntegralMall.entity.MembersUser;
import com.sxfq.loansupermarket.backsystem.modular.base.SqlMapper;
import com.sxfq.loansupermarket.backsystem.modular.weixin.config.AesUtil;
import com.sxfq.loansupermarket.backsystem.modular.weixin.config.WebChatConfig;
import com.sxfq.loansupermarket.backsystem.modular.weixin.service.IWxService;
import com.sxfq.loansupermarket.backsystem.modular.weixin.entity.WxTokenInfo;
import com.sxfq.loansupermarket.backsystem.modular.weixin.service.impl.MyX509TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.sxfq.loansupermarket.backsystem.modular.weixin.config.SignUtil;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 微信开发者接入
 *
 * @author Administrator
 */
@Controller
@RequestMapping("/wxWeixin")
public class WeixinController extends BaseController {
    @Autowired
    private SqlMapper sqlMapper;

    @Autowired
    private IWxService wxService;

    protected final static Logger logger = LoggerFactory.getLogger(GunsApplication.class);

    @ResponseBody
    @RequestMapping(value = "/getOpenid", method = RequestMethod.GET)
    public String getOpenid(String code) {
        return wxService.getOpenid(code);
    }

    @ResponseBody
    @RequestMapping(value = "/getAccessToken", method = RequestMethod.GET)
    public String getAccessToken() {
        String accessToken = "";
        String getTokenSql = "select access_token as accessToken from wx_parameter_info where app_id='" + WebChatConfig.APPID + "' limit 1";
        WxTokenInfo wxTokenInfo = sqlMapper.selectOne(getTokenSql, WxTokenInfo.class);
        if (wxTokenInfo == null) {
            accessToken = WebChatConfig.getToken(WebChatConfig.APPID, WebChatConfig.SECERT).getAccessToken();
            String updTokenSql = "update wx_parameter_info set access_token='" + accessToken + "' where app_id='" + WebChatConfig.APPID + "';";
            sqlMapper.update(updTokenSql);
        } else {
            if ("".equals(wxTokenInfo.getAccessToken()) || "null".equals(wxTokenInfo.getAccessToken())) {
                accessToken = WebChatConfig.getToken(WebChatConfig.APPID, WebChatConfig.SECERT).getAccessToken();
                String updTokenSql = "update wx_parameter_info set access_token='" + accessToken + "' where app_id='" + WebChatConfig.APPID + "';";
                sqlMapper.update(updTokenSql);
            }
            accessToken = wxTokenInfo.getAccessToken();
        }
        return accessToken;
    }

//    @ResponseBody
//    @RequestMapping(value = "/getWxUserInfoList", method = RequestMethod.GET)
//    public Map getWxUserInfoList(String code, String encryptedData, String iv) {
//        String accessToken=getAccessToken();
//        String URL = ("https://api.weixin.qq.com/cgi-bin/user/get?access_token=accessToken").replace("accessToken", accessToken);
//        JSONObject jsonObject = httpRequest(URL, "GET", null);//发送请求
//        // 如果请求成功
//        if (null != jsonObject) {
//            return jsonObject;
//        } else {
//            return null;
//        }
//    }

    @ResponseBody
    @RequestMapping(value = "/getWxUserInfoList", method = RequestMethod.GET)
    public Map getWxUserInfoList(String code, String encryptedData, String iv) {
        String accessToken=getAccessToken();
        String URL = ("https://api.weixin.qq.com/cgi-bin/user/get?access_token=accessToken").replace("accessToken", accessToken);
        JSONObject jsonObject = httpRequest(URL, "GET", null);//发送请求
        // 如果请求成功
        if (null != jsonObject) {
            JSONObject a = jsonObject.getJSONObject("data");
            System.out.println(a);
            JSONArray arrayList = a.getJSONArray("openid");
            for(Object awrray : arrayList){
                System.out.println(awrray);
                String intosql ="insert into open_info_copy (open_id) values ('"+awrray+"')";
                sqlMapper.insert(intosql);
            }
            return jsonObject;
        } else {
            return null;
        }
    }

    @ResponseBody
    @RequestMapping(value = "/getWxUserInfo", method = RequestMethod.GET)
    public Map getWxUserInfo(String code, String encryptedData, String iv) {
        Map<String, Object> map = new HashMap<String, Object>();
        if (code == null || code.length() == 0) {//登录凭证不能为空
            map.put("status", 0);
            map.put("msg", "code 不能为空");
            System.out.println("map1:" + map);
            ShiroKit.setSessionAttr("wxcode", ShiroKit.getSessionAttr("wxcode"));
            return map;
        } else {
            if (code.equals(ShiroKit.getSessionAttr("wxcode"))) {

            } else {
                ShiroKit.setSessionAttr("wxcode", code);
            }
        }
        //小程序唯一标识   (在微信小程序管理后台获取)
        String wxspAppid = WebChatConfig.APPID;//wx617f2a7161b844e2 wx77017898334e6e7b
        //小程序的 app secret (在微信小程序管理后台获取)
        String wxspSecret = WebChatConfig.SECERT;//2bd57f9adfb912d35cf282e4d79e4205 731fbf6d20a5925c3be5caaa9c4eee07
        //////////////// 1、向微信服务器 使用登录凭证 code 获取 session_key 和 openid ////////////////
        String URL = ("https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type" +
                "=authorization_code").replace("APPID", wxspAppid).replace("SECRET", wxspSecret).replace("CODE", ShiroKit.getSessionAttr("wxcode"));
        JSONObject json = httpRequest(URL, "GET", null);//发送请求
        //获取会话密钥（session_key）
        String session_key = json.get("session_key").toString();
        //用户的唯一标识（openid）
        String openid = (String) json.get("openid");
        System.out.println("openid:" + openid);
        //////////////// 2、对encryptedData加密数据进行AES解密 ////////////////
        try {
            String result = AesUtil.decrypt(encryptedData, session_key, iv, "UTF-8");
            if (null != result && result.length() > 0) {
                map.put("status", 1);
                map.put("msg", "解密成功");
                JSONObject userInfoJSON = JSONObject.parseObject(result);
                Map<String, Object> userInfo = new HashMap<String, Object>();
                userInfo.put("openId", userInfoJSON.get("openId"));
                userInfo.put("nickName", userInfoJSON.get("nickName"));
                userInfo.put("gender", userInfoJSON.get("gender"));
                userInfo.put("city", userInfoJSON.get("city"));
                userInfo.put("province", userInfoJSON.get("province"));
                userInfo.put("country", userInfoJSON.get("country"));
                userInfo.put("avatarUrl", userInfoJSON.get("avatarUrl"));
                userInfo.put("unionId", userInfoJSON.get("unionId"));
                map.put("userInfo", userInfo);
                System.out.println("map2:" + map);
                return map;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        map.put("status", 0);
        map.put("msg", "解密失败");
        System.out.println("map3:" + map);
        return map;
    }


    /**
     * 微信消息推送的验证。
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "sendMsg", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
    public void sendMsgget(HttpServletRequest request, HttpServletResponse response) {
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");

        PrintWriter out = null;
        try {
            out = response.getWriter();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，表示接入成功，否则接入失败
        if (SignUtil.checkSignature(signature, timestamp, nonce)) {
            out.print(echostr);
        }
        out.close();
        out = null;
    }

    /**
     * 发起https请求并获取结果
     *
     * @param requestUrl    请求地址
     * @param requestMethod 请求方式（GET、POST）
     * @param outputStr     提交的数据
     * @return JSONObject(通过JSONObject.get ( key)的方式获取json对象的属性值)
     */
    private static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = {new MyX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);
            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            jsonObject = JSONObject.parseObject(buffer.toString());
            // jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            System.out.println("Weixin server connection timed out.");
        } catch (Exception e) {
            System.out.println("https request error:{}" + e.getMessage());
        }
        return jsonObject;
    }
}